﻿<%@ WebHandler Language="C#" Class="Json" %>

using System;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using CommonLib.Extended;
using SqlSugar;
using WebApplication1.Base;


/// <summary>
/// Json 的摘要说明
/// </summary>
public class Json : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        context.Response.ContentType = "text/plain";

        string mode = context.Request["mode"].ToString();
        string tn = context.Request["tn"].ToString();
        switch (mode)
        {
            case "NumSelect"://查询表中grade数量
                {
                    string str = "["; string ls = "";

                    var list = DbSql.DB.Ado.SqlQuery<dynamic>("select distinct grade from " + tn + " order by grade");
                    foreach (var item in list)
                    {
                        str += ls + "{\"num\":\"" + item.grade.ToString() + "\"}";
                        ls = ",";
                    }
                    str += "]";
                    context.Response.Write(str);
                    break;
                }
            case "select"://查询
                {
                    if (context.Request["Level"] != null && context.Request["id"] == null && context.Request["value"] == null)//grade 没有id的时候 
                    {
                        context.Response.Write(GetJsonTreeStatic(tn, context.Request["Level"].ToString()));
                    }
                    else if (context.Request["id"] != null)
                    {
                        int pid = (context.Request["id"] != null) ? context.Request["id"].ToString().Int() : 0;
                        string json = GetJsonTree(tn, pid);
                        context.Response.Write(json);
                    }
                    else if (context.Request["value"] != null)
                    {
                        var levels = DbSql.DB.Ado.SqlQuerySingle<string>("select levels from " + tn + " where value='" + context.Request["value"].ToString() + "'");
                        context.Response.Write(GetJsonTreeStatic(tn, "", levels));
                    }
                    break;
                }
            case "insert"://添加节点
                {
                    string levels = ""; string grade = "";
                    Layer_Level(tn, context.Request["pid"].ToString().Int(), out grade, out levels);

                    var dc = new System.Collections.Generic.Dictionary<string, object>();
                    dc.Add("pid", context.Request["pid"].ToString());
                    dc.Add("name", "新建节点");
                    dc.Add("grade", grade);
                    dc.Add("levels", levels);
                    dc.Add("leaf", "True");
                    dc.Add("url", "");
                    dc.Add("isdel", "0");
                    dc.Add("state", "closed");
                    dc.Add("disable", "是");
                    dc.Add("value", "");
                    DbSql.DB.Insertable(dc).AS(context.Request["tn"].ToString()).ExecuteCommand();
                    var maxid = DbSql.DB.Ado.SqlQuerySingle<string>("select max(id) from " + tn);

                    UpdateLeaf(context.Request["pid"].ToString().Int(), tn);//更新父节点 leaf 
                    context.Response.Write(maxid);
                    break;
                }
            case "edit":
                {
                    //编辑节点name
                    DbSql.DB.Ado.ExecuteCommand("UPDATE " + tn + " SET name = '" + context.Request["name"].ToString() + "' WHERE id = '" + context.Request["id"].ToString() + "'");
                    break;
                }
            case "delete"://删除节点
                {
                    int pid = DbSql.DB.Ado.SqlQuerySingle<string>("select pid from " + tn + " where id='" + context.Request["id"].ToString() + "'").Int();
                    if (pid > 0)//第一个根节点不能删除 
                    {
                        string Layer = DbSql.DB.Ado.SqlQuerySingle<string>("select levels from " + tn + " where id='" + context.Request["id"].ToString() + "'");
                        //DbHelper.ExecuteNonQuery("DELETE FROM " + tn + " WHERE (id = '" + context.Request["id"].ToString() + "')");
                        DbSql.DB.Ado.ExecuteCommand("UPDATE " + tn + " SET isdel = 1 WHERE (id = '" + context.Request["id"].ToString() + "')");
                        UpdateLeaf(pid, tn); //更新父节点 leaf
                    }
                    break;
                }
            case "move"://移动节点
                {
                    string id = context.Request["id"].ToString();//移动的节点
                    int targetId = context.Request["targetId"].ToString().Int();//移动到的 父节点
                    string point = context.Request["point"].ToString();//移动方式
                    if (point == "append")//append,top,bottom； append:才做拖拽处理
                    {
                        int targetId_Level = Convert.ToInt32(DbSql.DB.Ado.SqlQuerySingle<string>("select grade from " + tn + " where id='" + targetId + "'"));
                        string old_Layer = ""; int id_Level = 0; int pid = 0;
                        var list = DbSql.DB.Ado.SqlQuery<dynamic>("select pid,levels,grade from " + tn + " where id='" + id + "'");
                        foreach (var item in list)
                        {
                            id_Level = Convert.ToInt32(item.grade.ToString());
                            old_Layer = item.levels.ToString();
                            pid = item.pid.ToString().Int();
                        }

                        if (pid != targetId)//移动本原来levels 不做任何处理
                        {
                            //更新移动到的节点 leaf
                            DbSql.DB.Ado.ExecuteCommand("UPDATE " + tn + " SET leaf = 'False' WHERE id = '" + targetId + "'");

                            //更新移动节点 grade levels leaf pid
                            string new_Layer = ""; string new_Level = "";
                            Layer_Level(tn, targetId, out new_Level, out new_Layer);
                            DbSql.DB.Ado.ExecuteCommand(string.Format("UPDATE {0} SET pid ='{1}', grade ='{2}', levels ='{3}' WHERE (id = '{4}')", tn, targetId, new_Level, new_Layer, id));

                            //更新子级 levels grade pid不变
                            string sqlstr = string.Format(@"UPDATE {5}
                                                    SET grade = grade+{1}, levels ='{4}'+SUBSTRING(levels, {2}, LEN(levels) - {3})
                                                    WHERE (levels LIKE '{0}%')", old_Layer, targetId_Level - id_Level + 1, old_Layer.Length + 1, old_Layer.Length, new_Layer, tn);
                            DbSql.DB.Ado.ExecuteCommand(sqlstr);
                            UpdateLeaf(pid, tn);
                        }
                        else//拖动到原来的父节点 不做处理
                        {
                            context.Response.Write("refresh");
                        }
                    }
                    break;
                }
            case "up"://上移
                {
                    //获取上一个相邻节点
                    string id = context.Request["id"].ToString();
                    string sqlstr = string.Format(@"SELECT  c.id,c.levels
                                                    FROM {0} AS c INNER JOIN
                                                         {0} AS p ON c.pid = p.pid
                                                    WHERE (p.id = '{1}')
                                                    ORDER BY c.levels", tn, id);
                    string 本levels = ""; string upLevels = "";//string id = ""; 
                    var list = DbSql.DB.Ado.SqlQuery<dynamic>(sqlstr);
                    foreach (var item in list)
                    {
                        if (item.id.ToString() == id)
                        {
                            本levels = item.levels.ToString();
                            break;
                        }
                        upLevels = item.levels.ToString();
                    }
                    if (upLevels != "")
                    {
                        Up_Down(tn, upLevels, 本levels);
                    }
                    else
                    {
                        context.Response.Write("NO");
                    }
                    break;
                }
            case "down"://下移
                {
                    //获取下一个相邻节点
                    string id = context.Request["id"].ToString();
                    string sqlstr = string.Format(@"SELECT  c.id,c.levels
                                                    FROM {0} AS c INNER JOIN
                                                         {0} AS p ON c.pid = p.pid
                                                    WHERE (p.id = '{1}')
                                                    ORDER BY c.levels DESC", tn, id);
                    string 本levels = ""; string downLevels = "";//string id = "";
                    var list = DbSql.DB.Ado.SqlQuery<dynamic>(sqlstr);
                    foreach (var item in list)
                    {
                        if (item.id.ToString() == id)
                        {
                            本levels = item.levels.ToString();
                            break;
                        }
                        downLevels = item.levels.ToString();
                    }
                    if (downLevels != "")
                    {
                        Up_Down(tn, downLevels, 本levels);
                    }
                    else
                    {
                        context.Response.Write("NO");
                    }
                    break;
                }
        }

    }


    /// <summary>
    /// 同levels上移 下移
    /// </summary>
    /// <param name="Layer1">第一个节点levels</param>
    /// <param name="Layer1">第二个节点levels</param>
    private void Up_Down(string tn, string Layer1, string Layer2)
    {
        //把Layer1和子节点更新成 xxxx.xxxx.9999
        int lenght = Layer1.Length;
        string new_Layer1 = Layer1.Substring(0, Layer1.LastIndexOf(".")) + ".9999";
        DbSql.DB.Ado.ExecuteCommand(string.Format(@"UPDATE {0}
                                                SET levels = '{4}'+SUBSTRING(levels, {2}, LEN(levels) - {3})
                                                WHERE (levels LIKE '{1}%')", tn, Layer1, lenght + 1, lenght, new_Layer1));

        //更新Layer2和子节点为 Layer1 levels结构
        lenght = Layer2.Length;
        DbSql.DB.Ado.ExecuteCommand(string.Format(@"UPDATE {0}
                                                SET levels = '{4}'+SUBSTRING(levels, {2}, LEN(levels) - {3})
                                                WHERE (levels LIKE '{1}%')", tn, Layer2, lenght + 1, lenght, Layer1));

        //更新Layer1和子节点为 Layer2 levels结构
        lenght = Layer1.Length;
        DbSql.DB.Ado.ExecuteCommand(string.Format(@"UPDATE {0}
                                                SET levels = '{4}'+SUBSTRING(levels, {2}, LEN(levels) - {3})
                                                WHERE (levels LIKE '{1}%')", tn, new_Layer1, lenght + 1, lenght, Layer2));
    }

    /// <summary>
    /// 更新指定节点leaf
    /// </summary>
    /// <param name="id">节点id</param>
    /// <param name="tn">表名</param>
    private void UpdateLeaf(int id, string tn)
    {
        int num = Convert.ToInt32(DbSql.DB.Ado.SqlQuerySingle<string>("select count(*) from " + tn + " where pid='" + id + "' and isdel=0"));
        string leaf = num > 0 ? "False" : "True";
        DbSql.DB.Ado.ExecuteCommand("UPDATE " + tn + " SET leaf = '" + leaf + "' WHERE id = '" + id + "'");
    }

    /// <summary>
    /// 返回新添加接点的 grade levels 
    /// </summary>
    /// <param name="tn">表名</param>
    /// <param name="pid">pid</param>
    /// <param name="Level">grade</param>
    /// <param name="Layer">levels</param>
    private void Layer_Level(string tn, int pid, out string Level, out string Layer)
    {
        string _Layer = "";//父级 levels
        int _Level = 1; //子级 grade
        int cMaxLayer = 1;//子级最大levels
        string _pid = "0";

        var list = DbSql.DB.Ado.SqlQuery<dynamic>(string.Format("SELECT levels,grade FROM " + tn + " WHERE id ='{0}'", pid));
        foreach (var item in list)
        {
            _Layer = item.levels.ToString();
            _Level = Convert.ToInt32(item.grade.ToString()) + 1;

            string 子级levels = DbSql.DB.Ado.SqlQuerySingle<string>("SELECT IFNULL(levels,'') FROM " + tn + "  WHERE (levels LIKE '" + item.levels.ToString() + ".____') ORDER BY levels DESC LIMIT 1");
            if (子级levels != null && 子级levels != "")
            {
                cMaxLayer = Convert.ToInt32(子级levels.Substring(子级levels.LastIndexOf(".") + 1, 4)) + 1;
            }
        }

        Layer = _Layer + "." + AddZero(cMaxLayer.ToString(), 4);
        Level = _Level.ToString();
    }

    /// <summary>
    /// 补齐levels前面的 0
    /// </summary>
    /// <param name="num">要补齐的数字</param>
    /// <param name="length">长度</param>
    /// <returns></returns>
    private string AddZero(string num, int length)
    {
        string bl = "";//补零
        for (int i = 0; i < length - num.Length; i++)
        {
            bl += "0";
        }
        return bl + num;
    }


    /// <summary>
    /// 动态树json
    /// </summary>
    /// <returns></returns>
    public static string GetJsonTree(string tn, int pid, string value = "")
    {
        string str = "[";
        var list = DbSql.DB.Ado.SqlQuery<dynamic>("select id,name,grade,leaf,levels from " + tn + " where pid='" + pid + "' and isdel=0 order by levels");
        foreach (var item in list)
        {
            if (str != "[") str += ",";
            str += "{";
            str += "\"id\":\"" + item.id.ToString() + "\"";
            str += ",\"text\":\"" + item.name.ToString() + "\"";
            str += (item.leaf.ToString().ToLower() == "false") ? ",\"state\":\"closed\"" : ",\"state\":\"open\"";
            str += "}";
        }
        str += "]";

        return str;
    }


    /// <summary>
    /// 静态树菜单(网站_模块)
    /// </summary>
    /// <returns></returns>
    public static string GetJsonTreeStatic(string tn, string Level, string levels = "")
    {
        string where = " where isdel=0";
        if (Level != "")
        {
            where += " and grade<=" + Level;
        }
        if (levels != "")
        {
            where += " and levels like '" + levels + "%'";
        }
        var list = DbSql.DB.Ado.SqlQuery<dynamic>("select id,name,grade,leaf from " + tn + where + " order by levels");

        string str = "[{"; int pLevel = 1, cLevel = 1;
        foreach (var item in list)
        {
            cLevel = Convert.ToInt32(item.grade.ToString());
            //结束之前结点
            for (int i = 0; i < pLevel - cLevel; i++) str += "}]";
            //新父层出现
            if (pLevel > cLevel) str += "},{";
            //平层开始
            if (cLevel == pLevel && str.Length > 10) str += "},{";
            //子层开始
            if (cLevel > pLevel) str += ",\"children\":[{";

            str += "\"id\":\"" + item.id.ToString() + "\"";
            str += ",\"text\":\"" + item.name.ToString() + "\"";
            if (Convert.ToInt32(item.grade.ToString()) > 1)
            {
                str += (item.leaf.ToString().ToLower() == "false") ? ",\"state\":\"closed\"" : ",\"state\":\"open\"";
            }

            pLevel = cLevel;
        }
        //结束之前结点
        for (int i = 1; i < cLevel + 1; i++) str += "}]";
        return str;
    }
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
